package edu.faytechcc.csc.gui;

import edu.faytechcc.csc.business.Controller;
import edu.faytechcc.csc.business.Model;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;

/**
 * This class represents the main window for the Alice Class File editor. 
 * 
 * @author Charles Bryan
 */
public class AliceClassEditorWindow extends JPanel
        implements PropertyChangeListener
{

    private StudentPanel studentPanel;
    private AlicePanel alicePanel;
    private JButton convertButton;
    private DestinationPanel destinationPanel;
    private Controller controller;
    private JProgressBar progressBar;
    private JMenuItem convertItem;

    public AliceClassEditorWindow()
    {
        buildPanel();
    }

    /**
     * Create the GUI and show it. As with all GUI code, this must run
     * on the event-dispatching thread.
     */
    public static void createAndShowGUI()
    {
        //Create and set up the window.
        JFrame frame = new JFrame("CIS 115 *.a2c Processor");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        AliceClassEditorWindow newContentPane = new AliceClassEditorWindow();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //create and set up the menu bar
        frame.setJMenuBar(newContentPane.buildMenuBar());

        //Display the window.
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);
    }

    /**
     * Set up the look and feel of the panel. 
     */
    private void buildPanel()
    {

        this.setLayout(new BorderLayout());

        JPanel tempPanel = new JPanel();
        tempPanel.setLayout(new BoxLayout(tempPanel, BoxLayout.Y_AXIS));

        destinationPanel = new DestinationPanel();
        destinationPanel.setBorder(
                BorderFactory.createEmptyBorder(15, 10, 0, 10));

        tempPanel.add(destinationPanel);

        studentPanel = new StudentPanel();
        studentPanel.setBorder(
                BorderFactory.createEmptyBorder(10, 10, 10, 10));
        tempPanel.add(studentPanel);

        alicePanel = new AlicePanel();
        alicePanel.setBorder(
                BorderFactory.createEmptyBorder(10, 10, 10, 10));
        tempPanel.add(alicePanel);

        this.add(tempPanel, BorderLayout.CENTER);

        convertButton = new JButton("Convert");
        convertButton.addActionListener(new ConvertButtonActionListener());
        convertButton.setActionCommand("start");
        JPanel tempButtonPanel = new JPanel(new BorderLayout(10, 0));

        progressBar = new JProgressBar();
        progressBar.setValue(0);

        //Call setStringPainted now so that the progress bar height
        //stays the same whether or not the string is shown.
        progressBar.setStringPainted(true);

        tempButtonPanel.add(convertButton, BorderLayout.WEST);
        tempButtonPanel.add(progressBar, BorderLayout.CENTER);
        tempButtonPanel.setBorder(
                BorderFactory.createEmptyBorder(5, 25, 15, 25));

        this.add(tempButtonPanel, BorderLayout.SOUTH);
    }

    /**
     * Create and setup the Menu bar for the frame.
     * @return The menu bar for the frame
     */
    private JMenuBar buildMenuBar()
    {
        JMenuBar bar = new JMenuBar();
        bar.add(buildFileMenu());
        bar.add(buildCreateMenu());
        bar.add(buildHelpMenu());
        return bar;
    }

    /**
     * Create and setup the "File" menu for the menu bar.
     * @return The "File" menu.
     */
    private JMenu buildFileMenu()
    {
        JMenu file = new JMenu("File");
        file.setMnemonic('F');
        JMenuItem logItem = new JCheckBoxMenuItem("Enable Logging");
        logItem.setMnemonic('E');
        file.add(logItem);
        convertItem = new JMenuItem("Convert");
        convertItem.setMnemonic('C');
        file.add(convertItem);
        file.addSeparator();
        JMenuItem exitItem = new JMenuItem("Exit");
        exitItem.setMnemonic('x');
        file.add(exitItem);

        //adding action listener to menu items
        logItem.addActionListener(
                new ActionListener()
                {
                    //use this for the future impelentation.

                    @Override
                    public void actionPerformed(ActionEvent e)
                    {
                        //Enable Logging was clicked.
                        String message = "This is not implemented yet.";
                        JOptionPane.showMessageDialog(null, message,
                                "Opps!",
                                JOptionPane.ERROR_MESSAGE);
                    }
                });

        convertItem.addActionListener(
                new ConvertButtonActionListener());

        exitItem.addActionListener(
                new ActionListener()
                {
                    //eixt was clicked so exit the program

                    @Override
                    public void actionPerformed(ActionEvent e)
                    {
                        System.exit(0); //kill the app hard
                    }
                });
        return file;
    }

    /**
     * Create and setup the "Create" menu for the menu bar.
     * @return The "Create" menu. 
     */
    private JMenu buildCreateMenu()
    {
        JMenu create = new JMenu("Create");
        create.setMnemonic('C');
        JMenuItem studentItem = new JMenuItem("Create Student list file");
        studentItem.setMnemonic('S');
        create.add(studentItem);
        JMenuItem alicetItem = new JMenuItem("Create Alice list file");
        alicetItem.setMnemonic('A');
        create.add(alicetItem);

        //adding action listener to menu items
        studentItem.addActionListener(
                new ActionListener()
                {
                    //pop up the create student file window

                    @Override
                    public void actionPerformed(ActionEvent e)
                    {
                        javax.swing.SwingUtilities.invokeLater(new Runnable()
                        {
                            //start the application

                            @Override
                            public void run()
                            {
                                StudentListCreaterWindow.createAndShowGUI();
                            }
                        });

                    }
                });

        alicetItem.addActionListener(
                new ActionListener()
                {
                    //pop up the create Alice class file window

                    @Override
                    public void actionPerformed(ActionEvent e)
                    {
                        javax.swing.SwingUtilities.invokeLater(new Runnable()
                        {
                            //start the application

                            @Override
                            public void run()
                            {
                                AliceClassListCreatorWindow.createAndShowGUI();
                            }
                        });
                    }
                });

        return create;
    }

    /**
     * Create and setup the "Help" menu for the menu bar.
     * @return The "Help" menu. 
     */
    private JMenu buildHelpMenu()
    {
        JMenu help = new JMenu("Help");
        help.setMnemonic('H');
        JMenuItem docItem = new JMenuItem("Documentation");
        docItem.setMnemonic('D');
        help.add(docItem);
        JMenuItem aboutItem = new JMenuItem("About");
        aboutItem.setMnemonic('A');
        help.add(aboutItem);

        //adding action listener to menu items
        docItem.addActionListener(
                new ActionListener()
                {
                    //Pop up a message not implemented

                    @Override
                    public void actionPerformed(ActionEvent e)
                    {
                        JOptionPane.showMessageDialog(null, "Documentation "
                                + "not available.");
                    }
                });

        aboutItem.addActionListener(
                new ActionListener()
                {
                    //pop up a message about the program

                    @Override
                    public void actionPerformed(ActionEvent e)
                    {
                        String message = "CIS 115 *.a2c Processor\n\n"
                                + "Version 1.4\n\n"
                                + "Created by: \n"
                                + "Charles Bryan\n"
                                + "bryanc@faytechcc.edu";
                        JOptionPane.showMessageDialog(null, message);
                    }
                });

        return help;
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt)
    {
        //Used to "monitor" the progress of the Task. 
        if ("progress".equals(evt.getPropertyName()))
        {
            //progress has been updated so update the progress bar with a new %
            int progress = (Integer) evt.getNewValue();
            progressBar.setIndeterminate(false);
            progressBar.setValue(progress);
        }
        else if (evt.getNewValue().equals(SwingWorker.StateValue.DONE))
        {
            //the task is over, enable all disabled items and reset the cursor.
            this.convertButton.setEnabled(true);
            this.convertItem.setEnabled(true);
            setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }

    }

    /**
     * This method disables all buttons and sets the cursor to the wait cursor
     * just before it starts the conversion Algorithm via the Controller. It 
     * also adds the controller as PropertyChangeListener for the progress bar
     * purposes.
     * 
     * @param model The model with the current student and alice class 
     * information to be converted.
     */
    private void performConversion(Model model)
    {

        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        this.convertButton.setEnabled(false);
        this.convertItem.setEnabled(false);

        controller = new Controller(model);
        controller.addPropertyChangeListener(this);
        controller.execute();

    }

    /**
     * A private inner ActionaListener class used when either the convert button 
     * or convert menu item is clicked.
     */
    private class ConvertButtonActionListener implements ActionListener
    {

        @Override
        public void actionPerformed(ActionEvent e)
        {
            //used to hold error respnses from the child panels
            String errorMessage = "";

            Model model = new Model();

            errorMessage += studentPanel.getText(model);
            errorMessage += alicePanel.getText(model);
            errorMessage += destinationPanel.getText(model);
            if (!errorMessage.isEmpty())
            {
                //found some errors in the data entered. User must fix them.
                errorMessage = "The following items need to be corrected.\n\n"
                        + errorMessage;
                JOptionPane.showMessageDialog(null, errorMessage, "Opps!",
                        JOptionPane.ERROR_MESSAGE);
            }
            else
            {
                //Alls good, go convert the model.
                performConversion(model);
            }
        }
    }
}
